package com.iflytek.iot.platform.tracing.send;

import com.alibaba.fastjson.JSON;
import com.iflytek.drip.log.loglib.clients.ISendLog;
import com.iflytek.drip.log.loglib.config.CommonConfig;
import com.iflytek.drip.log.loglib.config.LogLibConfig;
import com.iflytek.drip.log.loglib.utils.EventDeliveryException;
import com.iflytek.iot.common.utils.StringUtils;
import com.iflytek.iot.platform.IotTraceLogEntity;
import com.iflytek.iot.platform.tracing.config.HostInfoConfig;
import com.iflytek.iot.platform.tracing.config.LogBackConfig;
import com.iflytek.iot.platform.tracing.config.LogBackConfigUtils;
import com.iflytek.iot.platform.tracing.config.TraceLogClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author ZuRun
 * @date 2020/10/10 15:37:32
 */
public class SendLogByFlume {

    private static final String APP_ID = "GRAY16VK";
    private static final String LOG_TYPE = "iotPlatformOpenApiLog";
    /**
     * 上一秒成功发送文件数
     */
    private static long last = 0;

    //该logger配置了logback.xml
    private final static Logger logger = LoggerFactory.getLogger("SendLogByFlume");

    //单例
    private static SendLogByFlume instance;

    public static SendLogByFlume getInstance() {
        if (instance == null) {
            synchronized (SendLogByFlume.class) {
                if (instance == null) {
                    instance = new SendLogByFlume();
                    instance.init();
                }
            }
        }
        return instance;
    }

    private ISendLog logClient;

    public ISendLog getLogClient() {
        return logClient;
    }

    public void setLogClient(ISendLog logClient) {
        this.logClient = logClient;
    }

    public void init() {

        try {
            TraceLogClient client = new TraceLogClient();
            client.configure("logback.properties", getConfig());
            // 初始化发送日志内容
            setLogClient(client);
            Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
                long total = client.getTotal();
                logger.debug("[drip monitor] used:{} cur:{} total:{} toFile:{} w2File:{} suc:{}",
                        client.getUsedQueueSize(), client.getSendQueueCurrentSize(),
                        total, client.getCountOfSendFromFile(),
                        client.getCountOfWToFile(), total - last);
                last = total;
            }, 0, 30_000, TimeUnit.MILLISECONDS);

        } catch (Exception e) {
            logger.error("/logback.properties init Exception", e);
        }
    }

    private LogLibConfig getConfig() {
        LogLibConfig logLibConfig = new LogLibConfig();
        LogBackConfig logBackConfig = LogBackConfigUtils.getLogConfig();
        CommonConfig commonConfig = new CommonConfig();
        commonConfig.setRoom(logBackConfig.getRoom());
        commonConfig.setLocalip(logBackConfig.getLocalip());
        commonConfig.setServerPort(logBackConfig.getPort());
        commonConfig.setCpname(logBackConfig.getCpname());

        logLibConfig.setCommonConfig(commonConfig);
        logLibConfig.setUseHttpSender(logBackConfig.getUseHttpSender());
        logLibConfig.setHostInfo(HostInfoConfig.getHostInfo(logBackConfig.getFlumeAgent()));
        logLibConfig.setLocalVaLogPath(logBackConfig.getLocalVaLogPath());
        logLibConfig.setSdkLogName(logBackConfig.getSdkLogName());
        logLibConfig.setLocalLogName(logBackConfig.getLocalLogName());
        logLibConfig.setStartCheck(logBackConfig.getStartCheck());
        logLibConfig.setFlumeConnectTimeOut(logBackConfig.getFlumeConnectTimeOut());
        logLibConfig.setFlumeRequestTimeOut(logBackConfig.getFlumeRequestTimeOut());
        logLibConfig.setSendQueueSize(logBackConfig.getSendQueueSize());
        logLibConfig.setPingIntervalTime(logBackConfig.getPingIntervalTime());
        logLibConfig.setIsUseSafeMod(logBackConfig.getIsUseSafeMod());
        logLibConfig.setPingTimeOut(logBackConfig.getPingTimeOut());
        logLibConfig.setSchedualIntervalTime(logBackConfig.getSchedualIntervalTime());
        logLibConfig.setFirstIntervalDelay(logBackConfig.getFirstIntervalDelay());
        logLibConfig.setScheduleLocalLogTimeOut(logBackConfig.getScheduleLocalLogTimeOut());
        logLibConfig.setBatchSize(logBackConfig.getBatchSize());
        logLibConfig.setConnectPoolSize(logBackConfig.getConnectPoolSize());
        logLibConfig.setNoTranferFillPercentage(logBackConfig.getNoTranferFillPercentage());
        String[] tempStr = {""};
        logLibConfig.setHorizontalSampleLogtypes(tempStr);
        logLibConfig.setVerticalSampleLogtypes(tempStr);
        logLibConfig.setVerticalSampleField(tempStr);
        logLibConfig.setBinFileWriteBatchSize(logBackConfig.getBinfileWiteBatchSize());
        logLibConfig.setMsgMaxSize(logBackConfig.getMsgMaxSize());
        return logLibConfig;
    }

    public static void sendLog(String logJsonString) {
        try {
            if (getInstance().getLogClient() != null) {
                getInstance().getLogClient().sendLog(APP_ID, LOG_TYPE, JSON.parseObject(logJsonString, Map.class));
            }
        } catch (EventDeliveryException e) {
            logger.error("sendLog EventDeliveryException", e);
        } catch (Exception e) {
            logger.error("sendLog Exception", e);
        }
    }

    public static void sendLog(String logType, Map<String, String> map, String sequenceNo) {
        logger.info("kafka es 日志写入.....");
        try {
            if (getInstance().getLogClient() != null) {
                setLogMap(map, sequenceNo);
                getInstance().getLogClient().sendLog(logType, map, null);
            }
        } catch (EventDeliveryException e) {
            logger.error("sequenceNo = {}; sendLog EventDeliveryException", sequenceNo, e);
            e.printStackTrace();
        } catch (Exception e) {
            logger.error("sequenceNo = {}; sendLog Exception", sequenceNo, e);
            e.printStackTrace();
        }
    }


    public static void setLogMap(Map<String, String> map, String sequenceNo) {
        try {
            Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();

            while (it.hasNext()) {
                Map.Entry<String, String> entry = it.next();

                String key = entry.getKey();
                String value = entry.getValue();

                if (StringUtils.isEmpty(value) || "class".equals(key)) {
                    it.remove();
                }

            }
        } catch (Exception e) {
            logger.error("sequenceNo={}; 设置logmap数据失败", sequenceNo);
        }
    }

}
